from hashlib import sha256  # 用于用户密码哈希处理
from datetime import datetime  # 用于时间戳生成
import random  # 随机数库
import click  # 用于创建命令行指令
# 导入 数据库实例化对象
from models import db, User, Movie


def register_commands(app):
    # ==============================================================================
    # 4. 命令行指令：用于数据库初始化、测试数据生成（通过flask cli调用）
    # ==============================================================================
    @app.cli.command('init-db')
    @click.option('--drop', is_flag=True, help='删除现有表后重建（可选参数）')
    def init_db(drop):
        """初始化数据库：创建所有数据表（支持先删后建）"""
        if drop:  # 如果指定--drop参数，先删除所有已存在的表
            db.drop_all()
        db.create_all()  # 创建所有模型对应的表
        click.echo('✅ 数据库初始化成功！')  # 命令行输出成功提示

    @app.cli.command('forge')
    @click.option('--movies', '-m', default=10, help='生成电影数量（默认10部）')
    @click.option('--users', '-u', default=3, help='生成普通用户数量（默认3个）')
    def forge(movies, users):
        """批量生成测试数据：包括管理员用户、普通用户、电影数据（会清除现有数据）"""
        # 1. 清除现有数据（先删后建，避免重复）
        db.drop_all()
        db.create_all()

        # 2. 生成测试用户数据
        # 普通用户模板（按指定数量生成）
        test_users = [
            {
                "username": f"user{i}",
                "email": f"user{i}@example.com",
                "password": f"password{i}"
            } for i in range(1, users + 1)
        ]

        # 添加管理员用户（固定账号，密码哈希为示例值，实际使用需修改）
        admin_user = User(
            username="admin",
            email="admin@example.com",
            password_hash="pbkdf2:sha256:150000$XXXXXXXX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            created_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 当前时间格式化
        )
        db.session.add(admin_user)  # 将管理员用户添加到数据库会话

        # 添加普通用户（密码通过sha256简单哈希处理，实际生产环境建议用werkzeug.security）
        for user_data in test_users:
            # 密码哈希生成：拼接前缀+sha256加密后的字符串
            password_hash = f"hash_{sha256(user_data['password'].encode()).hexdigest()}"
            user = User(
                username=user_data["username"],
                email=user_data["email"],
                password_hash=password_hash,
                created_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            )
            db.session.add(user)  # 将普通用户添加到数据库会话

        # 3. 生成测试电影数据
        genres = ["动作", "科幻", "喜剧", "剧情", "悬疑", "爱情", "动画", "冒险"]  # 电影类型列表
        movie_titles = [
            "星际穿越", "盗梦空间", "复仇者联盟", "肖申克的救赎", "霸王别姬",
            "阿甘正传", "泰坦尼克号", "蝙蝠侠：黑暗骑士", "教父", "指环王",
            "哈利波特", "蜘蛛侠", "变形金刚", "速度与激情", "侏罗纪公园"
        ]  # 电影标题列表

        for i in range(movies):
            # 处理标题：如果生成数量超过标题列表长度，自动拼接序号避免重复
            if i >= len(movie_titles):
                title = f"{movie_titles[i % len(movie_titles)]}{i + 1}"
            else:
                title = movie_titles[i]

            # 随机生成电影属性
            genre = random.choice(genres)  # 随机选择类型
            year = random.randint(1990, 2024)  # 随机年份（1990-2024）
            rating = round(random.uniform(7.0, 9.8), 1)  # 随机评分（7.0-9.8，保留1位小数）

            # 创建电影实例
            movie = Movie(
                title=title,
                year=year,
                genre=genre,
                rating=rating,
                poster_url=f"https://via.placeholder.com/300x450?text={title}",  # 占位图URL
                description=f"{title}是一部精彩的{genre}电影，上映于{year}年，获得了{rating}的高分评价。",
                created_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                updated_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            )
            db.session.add(movie)  # 将电影添加到数据库会话

        # 提交会话：将所有数据写入数据库
        db.session.commit()
        # 命令行输出结果提示
        click.echo(f'✅ 测试数据生成完成！')
        click.echo(f'- 生成用户：{users + 1} 个（含1个管理员 + {users}个普通用户）')
        click.echo(f'- 生成电影：{movies} 部')
